//========================================================================
// *作者：海盗猫  主页：ilplay.com
// *脚本：HDMAssembly
// *描述：
// *?2021 MYJL . All rights reserved.
//* ======================================================================
using System;
using UnityEngine;
using System.Reflection;
using System.Collections.Generic;

namespace HDMCode.Hotfix
{
    public static class HDMAssembly
    {
        public static Dictionary<string, byte[]> hotFoxAssemblyDict = new Dictionary<string, byte[]>();
        public static Dictionary<string, byte[]> mateDateAssemblyDict = new Dictionary<string, byte[]>();

        /// <summary>
        /// 为对象动态添加一个组件
        /// </summary>
        /// <typeparam name="T">组件类型</typeparam>
        /// <param name="gameObject">需要挂载的对象</param>
        /// <param name="assemblyName">组件所在程序集</param>
        /// <param name="scriptName">组件名称</param>
        /// <returns></returns>
        public static void AddComponent(GameObject gameObject, string assemblyName, string scriptName) 
        {
            try
            {
                byte[] assemblyFile = hotFoxAssemblyDict[assemblyName];
                Assembly assembly = Assembly.Load(assemblyFile);
                Type script = assembly.GetType(scriptName);
                gameObject.AddComponent(assembly.GetType(scriptName));
                //return script as T;
            }
            catch (Exception error)
            {
                Debug.LogError($"添加组件失败，请检查对象是否为空或者方法是否存在！{error}");
                //return default;
            }
        }

        /// <summary>
        /// 实例化脚本
        /// </summary>
        /// <typeparam name="T">脚本类型</typeparam>
        /// <param name="assemblyName">程序集名称</param>
        /// <param name="scriptName">脚本名称</param>
        /// <returns></returns>
        public static T NewScriptInstance<T>(string assemblyName, string scriptName) where T : class
        {
            try
            {
                byte[] assemblyFile = hotFoxAssemblyDict[assemblyName];
                Assembly assembly = Assembly.Load(assemblyFile);
                Type script = assembly.GetType(scriptName);
                T intance = Activator.CreateInstance(script) as T;
                return intance;
            }
            catch (Exception error)
            {
                Debug.LogError($"动态实例化脚本失败请检查方法是否存在！{error}");
                return default;
            }
        }

        /// <summary>
        /// 调用一个静态方法
        /// </summary>
        /// <typeparam name="T">脚本类型</typeparam>
        /// <param name="assemblyName">程序集名称</param>
        /// <param name="scriptName">脚本名称</param>
        /// <param name="functionName">方法名称</param>
        /// <returns></returns>
        public static MethodInfo CallFunction(string assemblyName, string scriptName, string functionName)
        {
            try
            {
                byte[] assemblyFile = hotFoxAssemblyDict[assemblyName];
                Assembly assembly = Assembly.Load(assemblyFile);
                Type script = assembly.GetType(scriptName);
                MethodInfo method = script.GetMethod(functionName);
                return method;
            }
            catch (Exception error)
            {
                Debug.LogError($"调用方法请检查对象是否为空或者方法是否存在！{error}");
                return default;
            }
        }

        /// <summary>
        /// 创建一个委托方法
        /// </summary>
        public static void CreatAction(string assemblyName, string scriptName, string functionName)
        {
            byte[] assemblyFile = hotFoxAssemblyDict[assemblyName];
            Assembly assembly = Assembly.Load(assemblyFile);
            Type entryType = assembly.GetType(scriptName);
            MethodInfo method = entryType.GetMethod(functionName);
            Action mainFunc = (Action)Delegate.CreateDelegate(typeof(Action), method);
            mainFunc();
        }
    }
}